package Compiler;
import java.io.*;
import java.util.*;

public class Lexical implements LexicalAnalyzer {
	//instantiates all that is needed for the lexical to run
	//currentpositionn is init to 0 so that every line always starts at the beginning
	//sourceline is just the next line

    String sourceLine;
    String nextToken = "";
    char NextChar;
    Terminal token;
    int currentPosition;
    Scanner file;
    public Lexical(String c) throws FileNotFoundException{
    	file = new Scanner(new File(c));
    	sourceLine = file.nextLine();
    	while(file.hasNextLine()){
    	sourceLine = sourceLine + file.nextLine();	
    	}
    	NextChar = getChar();
    }
    //starts the analyzer off at the first line
    public void start(String line){
    	sourceLine = line;
    	currentPosition = 0;
    	getChar();
    	getNextToken();
    	
    }
    //adds the next char token to the nextToken variable so that it can be used to compare and print to the compiler
    //lookuptoken takes in the current character and makes sure it is legal within the LOLCODE
	@Override
	public void addChar() {
	nextToken = nextToken + NextChar;
	}
	//gets the crrentcharacter not read from the file
	public char getChar() {
		char fromFile = sourceLine.charAt(currentPosition);
		currentPosition++;
		return fromFile;
		
	}

	@Override
	public String getNextToken() {
        nextToken = "";
        
		while(isSpace(NextChar)){
			NextChar = getChar();
		}
	    if(!Hash(NextChar)){
	    	while(!Hash(NextChar))
	    	{
	    		addChar();
	    		NextChar = getChar();
	    	}
	    	return nextToken;
	}

        else {
            while(!isSpace(NextChar)) 
                    {   
                        addChar();
                        NextChar = getChar();   
                    }
            if(nextToken.equalsIgnoreCase("#GIMMEH") || nextToken.equalsIgnoreCase("#MAEK") || nextToken.equalsIgnoreCase("#I"))
            {
                addChar();
                NextChar = getChar();
                    while(!isSpace(NextChar))
                    {
                        addChar();
                        NextChar = getChar();
                    }
            }         
            if(nextToken.equalsIgnoreCase("#I HAS"))
            {
                addChar();
                NextChar = getChar();
                    while(!isSpace(NextChar))
                    {
                        addChar();
                        NextChar = getChar();
                    }
            }

            if(lookupToken(nextToken))
            {   
                return nextToken;
            }
            else{
                System.err.println("SYNTAX ERROR: This is not a real terminal!" + nextToken);
                System.exit(0);
            }                    
            
            
        }
        return "error";               
}
	@Override
	public boolean isSpace(char c) {
		if ((c == ' ') || (c == '\t')) 
	    return true;
		else
		return false;
	}

	//makes sure that the hash code is defined and can be parsed
	private boolean Hash(char c){
		if(c == '#')
		return true;
		else
        return false;
	}
	@Override
	//looks up the token in the terminal class to make sure it is a legal token
	public boolean lookupToken(String c) {
		return (nextToken.equalsIgnoreCase(Terminal.DOC_BEGIN)) || (nextToken.equalsIgnoreCase(Terminal.DOC_END)) || (nextToken.equalsIgnoreCase(Terminal.COMMENT_BEGIN)) || (nextToken.equalsIgnoreCase(Terminal.COMMENT_END)) ||
	               (nextToken.equalsIgnoreCase(Terminal.HEAD_BEGIN)) || (nextToken.equalsIgnoreCase(Terminal.PARA_BEGIN)) || (nextToken.equalsIgnoreCase(Terminal.LIST_BEGIN)) || (nextToken.equalsIgnoreCase(Terminal.SECOND_END)) || 
	               (nextToken.equalsIgnoreCase(Terminal.TITLE_BEGIN)) || (nextToken.equalsIgnoreCase(Terminal.BOLD_BEGIN)) || (nextToken.equalsIgnoreCase(Terminal.ITALICS_BEGIN)) || (nextToken.equalsIgnoreCase(Terminal.ITEM_BEGIN)) ||
	               (nextToken.equalsIgnoreCase(Terminal.SOUND_BEGIN)) || (nextToken.equalsIgnoreCase(Terminal.VIDEO_BEGIN)) || (nextToken.equalsIgnoreCase(Terminal.NEWLINE)) || (nextToken.equalsIgnoreCase(Terminal.REST_END)) ||
	               (nextToken.equalsIgnoreCase(Terminal.BEGIN)) || (nextToken.equalsIgnoreCase(Terminal.MID)) || (nextToken.equalsIgnoreCase(Terminal.CALL));
	                    
	        }   
    public boolean moreChar()
    {        
        return (sourceLine.length() > currentPosition);
    }
    
/**
 *
 */
public void close()
    {
        file.close();
    }
	}


